<?php

namespace app\home\service;

use app\home\model\Order;
use app\home\model\Player;
use app\home\model\SysActivityInfo;
use app\home\model\TradeLog;
use app\home\model\UserFreeInfo;
use app\home\model\UserGameInfo;
use app\home\model\UserPropLog;
use app\home\model\UserPropsInfo;
use app\home\model\UserScoreLog;
use app\tools\BillingPoint;
use think\Cache;
use think\Db;

class NotifyService extends TradeLog
{

    protected $player_field = 'UserID,Score,Diamond,ChargeScore,TotalRecharge,SMoney,RechargeTimes,VipLevel,Lottery,LotteryPool,LotteryStock,LoginServer';

    protected $player_select = [];// 玩家查询到的字段
    protected $player_update = [];// 玩家待更新的字段
    protected $props_array = [];// 待发送的游戏道具
    protected $order_select = [];// 订单查询的结果

    /**
     * @param $order
     * @return bool
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function notifyProcess($order)
    {
        //防止同一用户统一时间回传数据被覆盖
        $userCache = Cache::get('Pay-'.$order['userid']);
        if($userCache){
            sleep(5);
        }
        Cache::set('Pay-'.$order['userid'],true,5);       

        $billing_id = $order['goods_id'];
        $UserID = $order['userid'];

        // 防止出现计费点找不到的情况
        $billing_point_array = BillingPoint::getBillingPointById($billing_id);
        if ($billing_point_array == false) {
            return false;
        }

        // 只允许计费点类型1000
        if ($billing_point_array['Type'] != 1000) {
            mylog($billing_id . ' not found');
            return false;
        }

        // 计费点的价格配置可能有异常
        if (!isset($billing_point_array['Price']) || !is_numeric($billing_point_array['Price'])) {
            mylog($billing_id . ' Price invalid');
            return false;
        }

        // 特殊处理比例不是1比10的情况
        if(isset($billing_point_array['SMoney'])){
            $SMoney = $billing_point_array['SMoney'];
        }else{
            $SMoney = $billing_point_array['Price'] * 10;
        }

        array_push($this->props_array, [3, $SMoney, 0]);
        $this->player_select = (new Player())->field($this->player_field)->where('UserID', $UserID)->find();
        $this->order_select = $order;
        /*充值赢大礼*/
        $this->Recharge_wins_big_gifts($UserID, $billing_point_array['Price'], $billing_id);

        /*充值道具活动*/
        // $item_arr = $this->Recharge_item_recharge_activity($UserID, $billing_point_array['Price']);
        // if (!empty($item_arr)) {
        //     $this->props_array = array_merge($this->props_array, $item_arr);
        // }
        /*处理Vip等级*/
        $oldVipLevel = $this->player_select['VipLevel'];
        $this->processVipLevel();

        // 开启事务
        try {
            $db = Db::connect('db_config2');
            $db->startTrans();
        } catch (\Exception $e) {
            mylog($e->getMessage());
            return false;
        }

        try {

            $time = date('Y-m-d H:i:s');

            $data['status'] = 1;
            $data['paydate'] = $time;
            $data['vip'] = $oldVipLevel;
//            $data['transactionID'] = json_encode(request()->param(),JSON_UNESCAPED_UNICODE);

            if ((new Order())->save($data, ['id' => $order['id']]) == false) {
                throw new \Exception('Order rollback');
            }

            $this->player_update['ChargeScore'] = $this->player_select['ChargeScore'] + $billing_point_array['Price'];
            $this->player_update['TotalRecharge'] = $this->player_select['TotalRecharge'] + $billing_point_array['Price'];
            $this->player_update['RechargeTimes'] = $this->player_select['RechargeTimes'] + 1;
            $this->player_update['SMoney'] = $this->player_select['SMoney'] + $SMoney;
            //业务需要--不该配置-当充值金额小于68的都给68 vip 等级为2
            // if($this->player_update['TotalRecharge'] < 68 && $this->player_update['TotalRecharge'] > 0){
            //     $this->player_update['TotalRecharge'] = 68;
            //     $this->player_update['VipLevel'] = 2;
            // }

            if ((new Player())->save($this->player_update, ['UserID' => $UserID]) == false) {
                throw new \Exception('Order rollback');
            }

             // 把充值总额写入到有序集合
             $redis = new \Redis();
             $redis->connect(config('REDIS_FORMAL.host'), config('REDIS_FORMAL.port'));
             $redis->auth(config('REDIS_FORMAL.auth'));
             $redis->select(0);
             $time = date("Ymd");
             $redis->zIncrBy('recharge_' . $time, $billing_point_array['Price'], $UserID);

             $redis->select(8);
             $redis->hIncrBy('recharge_smoney',$UserID,$SMoney);
            $db->commit();

            /*向游戏服务器发送充值消息*/
            if ($this->get_curl_type($UserID,$this->props_array,$oldVipLevel) == false) {
                mylog('通知服务器失败');
            }

            $this->Recharge_score_log();
            mylog('订单处理ok');
            //记录生成vip2的时候当时的数据
            if(isset($this->player_update['VipLevel']) && $this->player_update['VipLevel'] == 2){
                $this->isVip2($UserID);
            }
            return true;
        } catch (\Exception $e) {
            mylog('notify-error:'.$e->getMessage().' line:'.$e->getLine().' file:'.$e->getFile());
            $db->rollback();
            return false;
        }
    }
    public function isVip2($userId){
        $accounts_info = Db::connect('db_config2')->table('accounts_info')->where(['UserID'=>$userId])->find();
        $user_game_info = Db::connect('db_config2')->table('user_game_info')->where(['UserID'=>$userId])->find();
        $data =[
            'RegisterDate'=>$accounts_info['RegisterDate'],
            'UserID'=>$userId,
            'SpreaderID'=>$accounts_info['SpreaderID'],
            'vip2_time'=>date('Y-m-d H:i:s'),
            'TotalRecharge'=>$accounts_info['TotalRecharge'],
            'LotteryStock'=>$accounts_info['LotteryStock'],
            'Score'=>$accounts_info['Score'],
            'Cannon'=>$user_game_info['Cannon'],
        ];
        db('user_vip2','db_operatelog')->insert($data);
    }

    public function checkOrder($OrderId, $total_price)
    {
        try {
            $order_info = (new \app\home\model\TradeLog)->where('id', $OrderId)->find();

            if (empty($order_info)) {
                throw new \Exception('订单不存在');
            }

            if ($order_info['amount'] != $total_price) {
                throw new \Exception('订单金额不一致' . ' 传参:' . $total_price . ' 实际:' . $order_info['amount']);
            }

            return $order_info;
        } catch (\Exception $e) {
            mylog('订单异常:'.$e->getMessage());
            return false;
        }
    }

    protected function processVipLevel()
    {

        $level = vip_level($this->player_select['TotalRecharge'] + $this->order_select['amount']);   //充值后对应等级

        // 充值前的vip<2 充值后的vip>=2 鱼券奖池 -= 当前身上的金币
        if ($this->player_select['VipLevel'] < 2 && $level >= 2) {
            $this->player_update['LotteryPool'] = $this->player_select['LotteryPool'] - $this->player_select['Score'];
        }

        if ($level > $this->player_select['VipLevel']) {
            $this->player_update['VipLevel'] = $level;
        }

        return true;
    }

    /**
     * 通知游戏服务器
     * @param $UserID
     * @param array $dataArray
     * @return string   success
     * @throws \think\Exception
     */
    protected function get_curl_type($UserID, $dataArray = [],$oldVipLevel)
    {
        $cannon = (new UserGameInfo)->where('UserID', $UserID)->value('Cannon');
        $data = [
            'Type' => 1000,
            'RechargeStock' => 0,
            'Award' => $dataArray,
            'UserID' => (int)$UserID,
            'Cannon' => (int)$cannon,
            'Score' => (int)$this->player_select['Score'],
            'Diamond' => (int)$this->player_select['Diamond'],
            'GoodsID' => (int)$this->order_select['goods_id'],
            'channel_id' => (int)$this->order_select['channel_id'],
            'amount' => (int)$this->order_select['amount'],
            'SMoney' => (int)$this->player_update['SMoney'],
            'Recharge' => (int)$this->player_update['TotalRecharge'],
            'VipLevel' => isset($this->player_update['VipLevel'])?(int)$this->player_update['VipLevel']:(int)$this->player_select['VipLevel'],
            'oldVipLevel' => $oldVipLevel,
        ];
        $url_param = json_encode($data);
        // $url = getServerUrl($this->player_select['LoginServer']) . '?id=1&data=' . $url_param;

        $ip = Cache::get('notify'.$UserID);
        if(!empty($ip) && env('IS_DEVELOP') == 1){
            $url =$ip. '?id=1&data=' . $url_param;//方便调试
        }else{
            $url = env('PAY_URL') . '?id=1&data=' . $url_param;
        }
        serverLog('发送前'.date('Y-m-d H:i:s').$url);
        $res = curl_get($url);
        serverLog('调用结果:'.date('Y-m-d H:i:s').$res );
        if ($res === false || $res != 'success') {
            return false;
        }

        return true;
    }

    /**
     * 充值活动
     * @param $userid
     * @param $total_price
     * @param $Billing_point
     * @return string json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    protected function Recharge_wins_big_gifts($userid, $total_price, $Billing_point)
    {
        $total_price = (int)$total_price;
        $userid = (string)$userid;
        $activity = new SysActivityInfo();
        $arr = $activity->where('Charge', 1)->select();
        $data_info = array();
        foreach ($arr as $k => $v) {
            $start = strtotime($v['StartTime']);
            $end = strtotime($v['EndTime']) + 24 * 3600;
            if (time() > $start && time() < $end) {
                $row['ActivityID'] = $v['ActivityID'];
                $row['Clear'] = $v['Clear'];
                $row['StartTime'] = $v['StartTime'];
                $row['EndTime'] = $v['EndTime'];
                $row['Type'] = $v['Type'];
                $data_info[] = $row;
            }
        }
        foreach ($data_info as $k => $v) {
            $Clear = $v['Clear'];
            $ActivityID = $v['ActivityID'];
            if ($Clear == 1) {
                $time = date("Ymd", time());
                if ($v['Type'] != 1) {
                    /*  3001 充值送豪礼   3002  充值狂欢节  3003  打鱼狂欢节  3004  神器降世 */
                    $this->activity_recharge_hash($ActivityID, $userid, $total_price, $time, $Billing_point);
                } else {
                    $this->activity_recharge_zset($ActivityID, $userid, $total_price, $time, $Billing_point);
                }
            } else {
                $start = strtotime($v['StartTime']);
                $time = date("Ymd", $start);
                if ($v['Type'] != 1) {
                    $this->activity_recharge_hash($ActivityID, $userid, $total_price, $time, $Billing_point);
                } else {
                    $this->activity_recharge_zset($ActivityID, $userid, $total_price, $time, $Billing_point);
                }
            }
        }
    }

    /* 活动redis hash类型 */
    protected function activity_recharge_hash($ActivityID, $userid, $total_price, $time, $Billing_point)
    {
        $redis = new \Redis();
        $redis->connect(config('REDIS_FORMAL.host'), config('REDIS_FORMAL.port'));
        $redis->auth(config('REDIS_FORMAL.auth'));
        $redis->select(config('REDIS_FORMAL.dbindex'));
        $TotalRecharge = $this->player_select['TotalRecharge'];
        /*累计充值*/
        $total_recharge = $total_price + $TotalRecharge;
        switch ($ActivityID) {
            case 3001:
                $res = $redis->hget('activity_' . $ActivityID . '_' . $time, $userid);
                if ($res) {
                    $score = $res + $total_price;
                    $redis->hset('activity_' . $ActivityID . '_' . $time, $userid, $score);
                } else {
                    $redis->hset('activity_' . $ActivityID . '_' . $time, $userid, $total_price);
                }
                break;
            case 3002:
                if (!in_array($Billing_point, config('CARNIVA_RECHARGE')) && $total_recharge >= 6) {
                    $res = $redis->hget('activity_' . $ActivityID . '_' . $time, $userid);
                    if ($res) {
                        $score = $res + $total_price;
                        $redis->hset('activity_' . $ActivityID . '_' . $time, $userid, $score);
                    } else {
                        $redis->hset('activity_' . $ActivityID . '_' . $time, $userid, $total_price);
                    }
                }
                break;
            case 3005:
                $res = $redis->hget('activity_' . $ActivityID . '_' . $time, $userid);
                if ($res) {
                    $score = $res + $total_price;
                    $redis->hset('activity_' . $ActivityID . '_' . $time, $userid, $score);
                } else {
                    $redis->hset('activity_' . $ActivityID . '_' . $time, $userid, $total_price);
                }
                break;
            case 3004:
                $res = $redis->hget('activity_' . $ActivityID . '_' . $time, $userid);
                if ($res) {
                    $score = $res + $total_price;
                    $redis->hset('activity_' . $ActivityID . '_' . $time, $userid, $score);
                } else {
                    $redis->hset('activity_' . $ActivityID . '_' . $time, $userid, $total_price);
                }
                break;
        }
    }

    /* 活动redis 有序集合类型 zset 类型 */
    protected function activity_recharge_zset($ActivityID, $userid, $total_price, $time, $Billing_point)
    {
        $redis = new \Redis();
        $redis->connect(config('REDIS_FORMAL.host'), config('REDIS_FORMAL.port'));
        $redis->auth(config('REDIS_FORMAL.auth'));
        $redis->select(config('REDIS_FORMAL.dbindex'));
        $TotalRecharge = $this->player_select['TotalRecharge'];
        /*累计充值*/
        $total_recharge = $total_price + $TotalRecharge;
        switch ($ActivityID) {
            case 3001:
                $res = $redis->zScore('activity_' . $ActivityID . '_' . $time, $userid);
                if ($res) {
                    $score = $res + $total_price;
                    $redis->zAdd('activity_' . $ActivityID . '_' . $time, $score, $userid);
                } else {
                    $redis->zAdd('activity_' . $ActivityID . '_' . $time, $total_price, $userid);
                }
                break;
            case 3002:
                if (!in_array($Billing_point, config('CARNIVA_RECHARGE')) && $total_recharge >= 6) {
                    $res = $redis->hget('activity_' . $ActivityID . '_' . $time, $userid);
                    if ($res) {
                        $score = $res + $total_price;
                        $redis->hset('activity_' . $ActivityID . '_' . $time, $userid, $score);
                    } else {
                        $redis->hset('activity_' . $ActivityID . '_' . $time, $userid, $total_price);
                    }
                }
                break;
            case 3005:
                $res = $redis->zScore('activity_' . $ActivityID . '_' . $time, $userid);
                if ($res) {
                    $score = $res + $total_price;
                    $redis->zAdd('activity_' . $ActivityID . '_' . $time, $score, $userid);
                } else {
                    $redis->zAdd('activity_' . $ActivityID . '_' . $time, $total_price, $userid);
                }
                break;
            case 3004:
                $res = $redis->zScore('activity_' . $ActivityID . '_' . $time, $userid);
                if ($res) {
                    $score = $res + $total_price;
                    $redis->zAdd('activity_' . $ActivityID . '_' . $time, $score, $userid);
                } else {
                    $redis->zAdd('activity_' . $ActivityID . '_' . $time, $total_price, $userid);
                }
                break;
        }
    }

    /**
     * 充值活动
     * @param $userid
     * @param $total_price
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    protected function Recharge_item_recharge_activity($userid, $total_price)
    {
        // $arr = (new SysActivityInfo())->where('Charge', 1)->select();

        $prop = [];

        // foreach ($arr as $v) {
        //     $start = strtotime($v['StartTime']);
        //     $end = strtotime($v['EndTime']) + 24 * 3600;
        //     if (time() > $start && time() < $end) {

                // $ActivityID = $v['ActivityID'];
                // if (in_array($ActivityID, config('ITEM_RECHARGE_ACTIVITY'))) {
                //     $counts = intval(floor($total_price / 10));
                //     if ($counts >= 1) {
                //         $this->Gift_props($userid, 10126, $counts, 100);
                //         $this->Recharge_prop_log($userid, 10126, $counts);
                //         array_push($prop, [10126, $counts, 0]);
                //     }
                // }

                // if ($ActivityID == '3005') {
                //     $counts = intval(floor($total_price / 5));
                //     if ($counts >= 1) {
                //         $this->Gift_props($userid, 10106, $counts, 100);
                //         $this->Recharge_prop_log($userid, 10106, $counts);
                //         array_push($prop, [10106, $counts, 0]);
                //     }
                // }
        //     }
        // }

        return $prop;
    }

    /**
     * 充值道具日志记录
     * @param $UserID
     * @param $PropID
     * @param int $VarCounts
     * @return string json
     */
    protected function Recharge_prop_log($UserID, $PropID, $VarCounts = 0)
    {
        $Counts = (new UserPropsInfo())->where('UserID', $UserID)->where('PropID', $PropID)->value('Counts');
        $data['UserID'] = $UserID;
        $data['ServerID'] = 0;
        $data['GameName'] = '充值';
        $data['GameLevel'] = 0;
        $data['PropID'] = $PropID;
        $data['Counts'] = $Counts;
        $data['VarCounts'] = $VarCounts;
        $data['Type'] = '游戏充值';
        $data['RecordTime'] = date('Y-m-d H:i:s', time());
        UserPropLog::create($data);

        return true;
    }


    /*活动道具*/
    protected function Gift_props($UserID, $PropID, $Counts, $type = 1)
    {
        $data['UserID'] = $UserID;
        $data['PropID'] = $PropID;
        $data['Counts'] = $Counts;
        $data['Type'] = $type;
        $data['InserTime'] = date('Y-m-d H:i:s');
        $user_props_info = new UserPropsInfo();
        $res = $user_props_info->where('PropID', $PropID)->where('UserID', $UserID)->find();
        if ($res) {
            // 如果原来不是永久 就把其更新为永久
            $user_props_info->where('PropID', $PropID)->where('UserID', $UserID)->update(['ExpireTime' => '2099-01-01 00:00:00']);
            $re = $user_props_info->where('PropID', $PropID)->where('UserID', $UserID)->setInc('Counts', $Counts);
            if ($re) return true;
        } else {
            $re = $user_props_info->insert($data);
            if ($re) return true;
        }

        return false;
    }

    protected function Recharge_score_log()
    {

        $data['UserID'] = $this->player_select['UserID'];
        $data['SpreaderID'] = 0;
        $data['ServerID'] = 0;
        $data['GameName'] = '充值';
        $data['GameLevel'] = 0;
        $data['Type'] = '游戏充值';
        $data['Score'] = $this->player_select['Score'];
        $data['Lottery'] = $this->player_select['Lottery'];
        $data['Stock'] = $this->player_select['LotteryStock'];
        $data['Diamond'] = $this->player_select['Diamond'];
        // $data['SMoney'] = $arr['SMoney'];
        $data['VarScore'] = 0;
        $data['VarLottery'] = 0;
        $data['VarStock'] = 0;
        $data['VarDiamond'] = 0;
        $data['RecordTime'] = date('Y-m-d H:i:s', time());
        UserScoreLog::create($data);

        return true;
    }

    /**
     * @param $UserID
     * @param $billing_point_array
     * @return bool
     */
    public function processPlusExpireTime($UserID, $billing_point_array)
    {
        // 送对应的天数 1元=1天
        $user_free_info = new UserFreeInfo();
        $expire_time = $user_free_info->where('UserID', $UserID)->value('PlusExpireTime');
        if ($expire_time) {
            if (strtotime($expire_time) < time()) {
                $expire_day = date('Y-m-d H:i:s', time() + $billing_point_array["Price"] * 3600 * 24);
            } else {
                $expire_day = date('Y-m-d H:i:s', strtotime($expire_time) + $billing_point_array["Price"] * 3600 * 24);
            }
            if($user_free_info->where('UserID', $UserID)->setField('PlusExpireTime', $expire_day) == false){
                return false;
            }
        }

        return true;
    }
}